load "items.rb"
load "types.rb"
load "accessors_definition.rb"

def to_param_name(name)
	strs = name.split("_")
	out = ""
	first = true
	strs.each do |str|
		if first
			out += str.downcase
			first = false
		else
			out += str.capitalize
		end
	end
	return out
end

def to_member_name(name)
	strs = name.split("_")
	out = "m"
	strs.each do |str|
		out += str.capitalize
	end
	return out
end

def to_accessor_name(name)
	strs = name.split("_")
	out = ""
	strs.each do |str|
		out += str.capitalize
	end
	return out
end

def format(class_name, pattern)
	strs = []
	COMMONS.each_key do |type|
		COMMONS[type].each do |member|
			str = pattern.format(true, type, member, class_name)
			unless str.nil?
				strs << str
			end
		end
	end
	ITEMS[class_name].each_key do |type|
		ITEMS[class_name][type].each do |member|
			str = pattern.format(false, type, member, class_name)
			unless str.nil?
				strs << str
			end
		end
	end
	pattern.join(strs)
end

class Paramaters
	def self.format(commons, type, member, class_name)
		"#{PARAM_TYPES[type]} #{to_param_name(member)}"
	end

	def self.join(strs)
		strs.join(", ")
	end
end

class AccessorsDeclaration
	def self.format(commons, type, member, class_name)
		reader = "#{ACCESSOR_TYPES[type]} Get#{to_accessor_name(member)}() const;"
		writer = "void Set#{to_accessor_name(member)}(#{ACCESSOR_TYPES[type]} #{to_param_name(member)});"
		reader + "\n\t\t\t" + writer + "\n"
	end

	def self.join(strs)
		strs.join("\n\t\t\t")
	end
end

class SetValue
	def self.format(commons, type, member, class_name)
		if commons
			"item->SetValue(\"#{member}\", #{to_param_name(member)});"
		else
			"#{class_name}->SetValue(\"#{member}\", #{to_param_name(member)});"
		end
	end

	def self.join(strs)
		strs.join("\n\t\t\t")
	end
end

class SetValueDb
	def self.format(commons, type, member, class_name)
		if commons
			"item->SetValue(\"#{member}\", #{class_name}->GetValue(\"#{member}\"));"
		else
			"new#{class_name.capitalize}->SetValue(\"#{member}\", #{class_name}->GetValue(\"#{member}\"));"
		end
	end

	def self.join(strs)
		strs.join("\n\t\t\t")
	end
end

class AccessorsDefinition
	def self.format(commons, type, member, class_name)
		strs = []
		ACCESSORS_DEFINITION.each do |line|
			str = String.new(line)
			str.gsub!(/\$\(accessor_type\)/, ACCESSOR_TYPES[type])
			str.gsub!(/\$\(class_name\)/, class_name.capitalize)
			str.gsub!(/\$\(accessor_name\)/, to_accessor_name(member))
			if commons
				str.gsub!(/\$\(db\)/, 'mItem')
			else
				str.gsub!(/\$\(db\)/, "mDbItem")
			end
			str.gsub!(/\$\(col_type\)/, COLUMN_TYPES[type])
			str.gsub!(/\$\(col_name\)/, member)
			str.gsub!(/\$\(default_value\)/, DEFAULT_VALUES[type])
			str.gsub!(/\$\(member\)/, to_param_name(member))
			strs << str
		end
		strs.join("\t\t")
	end

	def self.join(strs)
		strs.join("\n\t\t")
	end
end

def write(template_name, out_filename, class_name)
	File.open("templates/#{template_name}", 'r') do |read_file|
		write_file = File.new("out/#{out_filename}", 'w')
		while line = read_file.gets
			line.gsub!(/\$\(class_name\)/, class_name.capitalize)
			line.gsub!(/\$\(db_name\)/, class_name)
			line.gsub!(/\$\(paramaters\)/, format(class_name, Paramaters))
			line.gsub!(/\$\(accessors_declaration\)/, format(class_name, AccessorsDeclaration))
			line.gsub!(/\$\(set_value\)/, format(class_name, SetValue))
			line.gsub!(/\$\(set_value_db\)/, format(class_name, SetValueDb))
			line.gsub!(/\$\(accessors_definition\)/, format(class_name, AccessorsDefinition))
			write_file.puts(line)
		end
		write_file.close
	end
end

ITEMS.each_key do |class_name|
	write('h_template', "#{class_name.capitalize}.h", class_name)
	write('cpp_template', "#{class_name.capitalize}.cpp", class_name)
end

